package com.zy.stock.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.sun.tools.doclets.internal.toolkit.util.DocFinder;
import com.zy.stock.domain.Pager;
import com.zy.stock.domain.Stock;
import com.zy.stock.domain.StockTranscation;
import com.zy.stock.domain.UserStockRl;
import com.zy.stock.dto.StockDto;
import com.zy.stock.mapper.StockMapper;
import com.zy.stock.mapper.StockTranscationMapper;
import com.zy.stock.mapper.UserStockRlMapper;
import com.zy.stock.service.StockService;
import com.zy.stock.util.CommonUtils;

@Component
@Transactional
public class StockServiceImpl implements StockService{
	
	private Logger logger = LoggerFactory.getLogger(StockServiceImpl.class);
	
	@Autowired
	private StockMapper stockMapper;
	
	@Autowired
	private UserStockRlMapper userStockRlMapper;
	
	@Autowired
	private StockTranscationMapper stockTranscationMapper;
	
	@Override
	public Pager<List<Stock>> findByCase(Pager<StockDto> pager)
			throws Exception {
		// TODO Auto-generated method stub
		Pager<List<Stock>> result = new Pager<List<Stock>>();
		try{
			StockDto obj = pager.getT();
			Integer total = stockMapper.getCount(obj);
			Integer totalpage = CommonUtils.getTotalPage(pager, total);
			Integer begin = (pager.getPagenow() - 1) * pager.getSize();
			obj.setStart(begin);
			obj.setSize(pager.getSize());
//			obj.setStart(0);
//			obj.setSize(10);
			obj.setOrder(pager.getOrder());
			obj.setOrderCol(pager.getOrderCol());
			List<Stock> list = stockMapper.findByCase(obj);
			result.setTotal(total);
			result.setT(list);
			result.setTotalpage(totalpage);
		}catch(Exception e){
			e.printStackTrace();
			throw new Exception("BillServiceImp.class findByCase function error : " + e.toString());
		}
		return result;
	}

	@Override
	public Integer save(Stock stock) throws Exception {
		// TODO Auto-generated method stub
		return stockMapper.save(stock);
	}

	@Override
	public Stock findById(Integer id) throws Exception {
		// TODO Auto-generated method stub
		return stockMapper.findById(id);
	}

	@Override
	public Integer update(Stock stock) throws Exception {
		// TODO Auto-generated method stub
		return stockMapper.update(stock);
	}

	@Override
	public void deleteById(Integer id) throws Exception {
		// TODO Auto-generated method stub
		stockMapper.deleteById(id);
	}

	@Override
	public List<Stock> findAll() throws Exception {
		// TODO Auto-generated method stub
		return stockMapper.findAll();
	}

	@Override
	public List<Stock> findByCode(String code) throws Exception {
		// TODO Auto-generated method stub
		return stockMapper.findByCode(code);
	}

	@Override
	public void dealShare(Integer baseStockNum, Integer shareStockNum,
			Integer baseCashNum, Double shareCash,Integer stockId) throws Exception {
		// TODO Auto-generated method stub
		List<UserStockRl> rls = userStockRlMapper.findShare(stockId);	
		for(UserStockRl rl:rls){
		  String jsonStr = JSONObject.toJSONString(rl);
		  if(baseCashNum!=null&&shareCash!=null){
			calculateCost(baseCashNum, shareCash,rl,jsonStr);//计算现金分红
		  }
		  if(baseStockNum!=null&&shareStockNum!=null){
		    dealStockShare(baseStockNum,shareStockNum,rl,jsonStr);//计算股票分红
		  }
		  //更新成本
		  userStockRlMapper.update(rl);
		}
	}

	/**
	 * 计算现金分红
	 * @param baseCashNum
	 * @param shareCash
	 * @param stockId
	 * @param rl
	 * @throws Exception 
	 */
	@Transactional(propagation=Propagation.REQUIRES_NEW) 
	private void calculateCost(Integer baseCashNum, Double shareCash,UserStockRl rl,String originRlJSON) throws Exception{
        //计算实际送了多少钱
		Double realShare = (rl.getNum()/baseCashNum)*shareCash;	
		//计算实际收入多少钱 交10%税
		BigDecimal incomeCash = new BigDecimal(realShare*0.9);
		//计算新的摊薄成本
		Double totalCost = rl.getNum()*rl.getCost();
		BigDecimal newCost = new BigDecimal((totalCost-incomeCash.doubleValue())/rl.getNum());
		newCost = newCost.setScale(2, BigDecimal.ROUND_HALF_UP);;
		rl.setCost(newCost.doubleValue());
			
		//保存现金分红记录
		StockTranscation st = new StockTranscation();
		st.setUserId(rl.getUserId());
		st.setUserName(rl.getUserName());
		st.setStockId(rl.getStockId());
		st.setStockCode(rl.getStockCode());
		st.setStockName(rl.getStockName());
		st.setUserStockRlId(rl.getId());
		st.setOperateNum(rl.getNum());
		st.setYears(rl.getYears());
		st.setOperation("现金分红");
		st.setStatus("已完成");
		st.setIncomeCash(incomeCash);
		st.setCreateTime(new Date());
		st.setDescription("每"+baseCashNum+"股"+"分现金"+shareCash+"元");
		
		//根据之前的状态判断 是否要根据之前状态计算
		if(StringUtils.isNotEmpty(originRlJSON)){
			st.setUserStockRlJsonStr(originRlJSON);
		}
		
		stockTranscationMapper.save(st);
	}
	
	private void dealStockShare(Integer baseStockNum, Integer shareStockNum,UserStockRl rl,String originRlJSON) throws Exception {
		// TODO Auto-generated method stub
	    //计算实际送了多少股
		Integer realShare = (rl.getNum()/baseStockNum)*shareStockNum;	
		double rate = (new Double(baseStockNum)+new Double(shareStockNum))/baseStockNum;
		//处理仓的持有数
		rl.setNum(realShare+rl.getNum());
		//处理成本
		BigDecimal newCost = new BigDecimal(rl.getCost()/rate);
		newCost = newCost.setScale(2, BigDecimal.ROUND_HALF_UP);
		rl.setCost(newCost.doubleValue());
		
		userStockRlMapper.update(rl);
		
		//处理股票的估值和预期收益变化
		//处理股票估值变换
		Stock stock = stockMapper.findById(rl.getStockId());
		BigDecimal newAppraisement= new BigDecimal(stock.getAppraisement()/rate);
		newAppraisement = newAppraisement.setScale(2, BigDecimal.ROUND_HALF_UP);			
		stock.setAppraisement(newAppraisement.doubleValue());
		//处理股票预期收益变化
		BigDecimal newEarnings= new BigDecimal(stock.getEarnings()/rate);
		newEarnings.setScale(2, BigDecimal.ROUND_HALF_UP);			
		stock.setEarnings(newEarnings.doubleValue());
		
		//保存现金分红记录
        StockTranscation st = new StockTranscation();
        st.setUserId(rl.getUserId());
        st.setUserName(rl.getUserName());
        st.setStockId(rl.getStockId());
        st.setStockCode(rl.getStockCode());
        st.setStockName(rl.getStockName());
        st.setUserStockRlId(rl.getId());
        st.setOperateNum(rl.getNum());
        st.setYears(rl.getYears());
        st.setOperation("股票分红");
        st.setStatus("已完成");
        st.setCreateTime(new Date());
        st.setDescription("每"+baseStockNum+"股"+"分股票"+shareStockNum+"股份");		
        
        
        //根据之前的状态判断 是否要根据之前状态计算
        if(StringUtils.isNotEmpty(originRlJSON)){
            st.setUserStockRlJsonStr(originRlJSON);
        }
        stockTranscationMapper.save(st);
		stockMapper.update(stock);
	}

  @Override
  public void dealUserRlShare(Integer baseStockNum, Integer shareStockNum, Integer baseCashNum,
      Double shareCash, Integer userRlId) throws Exception {
    // TODO Auto-generated method stub
    UserStockRl rl = userStockRlMapper.findById(userRlId);
    String jsonStr = JSONObject.toJSONString(rl);
    if(baseCashNum!=null&&shareCash!=null){
      calculateCost(baseCashNum,shareCash,rl,jsonStr);//计算现金分红
    }
    if(baseStockNum!=null&&shareStockNum!=null){
      dealStockShare(baseStockNum,shareStockNum,rl,jsonStr);//计算股票分红
    }
    //更新成本
    userStockRlMapper.update(rl);
  }

}
